package Generics;

import java.util.ArrayList;
import java.util.List;

public class GenericsMethod {

    // 泛型类型参数声明部分在方法返回类型之前
    // 泛型方法 printArray
    public static <E> void printArray(E[] inputArray) {
        // 输出数组元素
        for (E element : inputArray) {
            System.out.printf("%s ", element);
        }
        System.out.println();
    }

    // 比较三个值并返回最大值
    // extends Comparable<T> ，约束限制 T 需要继承自Comparable接口
    public static <T extends Comparable<T>> T maximum(T x, T y, T z) {
        T max = x; // 假设x是初始最大值
        if (y.compareTo(max) > 0) {
            max = y; // y 更大
        }
        if (z.compareTo(max) > 0) {
            max = z; // 现在 z 更大
        }
        return max; // 返回最大对象
    }

    /**
     * 类型通配符一般是使用?代替具体的类型参数 例如 List<?> 在逻辑上是List<String>,List<Integer>
     * 等所有List<具体类型实参>的父类。
     * 
     * @param <T>
     * @param data
     */
    public static <T> void getData(List<T> data) {
        System.out.println("data :" + data.get(0));
    }

    public static void getData1(List<?> data) {
        System.out.println("data :" + data.get(0));
    }

    /**
     * 上限 泛型约束: 类型通配符上限通过形如List来定义，如此定义就是通配符泛型值接受Number及其下层子类类型 只接受继承自 Number 的类型
     * 
     * @param data
     */
    public static void getUpperNumber(List<? extends Number> data) {
        System.out.println("data :" + data.get(0));
    }

    /**
     * 下限
     * 
     * @param data
     */
    public static void getUnderNumber(List<? super Number> data) {
        System.out.println("data :" + data.get(0));
    }

    public static void main(String[] args) {

        // 创建不同类型数组： Integer, Double 和 Character
        Integer[] intArray = { 1, 2, 3, 4, 5 };
        Double[] doubleArray = { 1.1, 2.2, 3.3, 4.4 };
        Character[] charArray = { 'H', 'E', 'L', 'L', 'O' };

        System.out.println("整型数组元素为:");
        printArray(intArray); // 传递一个整型数组

        System.out.println("\n双精度型数组元素为:");
        printArray(doubleArray); // 传递一个双精度型数组

        System.out.println("\n字符型数组元素为:");
        printArray(charArray); // 传递一个字符型数组

        System.out.printf("%d, %d 和 %d 中最大的数为 %d\n\n", 3, 4, 5, maximum(3, 4, 5));

        System.out.printf("%.1f, %.1f 和 %.1f 中最大的数为 %.1f\n\n", 6.6, 8.8, 7.7, maximum(6.6, 8.8, 7.7));

        System.out.printf("%s, %s 和 %s 中最大的数为 %s\n", "pear", "apple", "orange", maximum("pear", "apple", "orange"));



        
        List<String> name = new ArrayList<String>();
        List<Integer> age = new ArrayList<Integer>();
        List<Number> number = new ArrayList<Number>();
        List<Float> floats = new ArrayList<Float>();
        List<Object> objs = new ArrayList<Object>();

        name.add("icon");
        age.add(18);
        number.add(314);
        floats.add(1.25f);
        objs.add("123qwe");

        getData(name);
        getData(age);
        getData(number);
        getData(floats);
        getData(objs);

        getData1(name);
        getData1(age);
        getData1(number);
        getData1(floats);
        getData1(objs);

        // getUperNumber(name);// error
        getUpperNumber(age);// 2
        getUpperNumber(number);// 3
        getUpperNumber(floats);// 3
        // getUpperNumber(objs);// error

        // getUnderNumber(name);// error
        // getUnderNumber(age);// error
        getUnderNumber(number);
        // getUnderNumber(floats);// error
        getUnderNumber(objs);
    }
}
